﻿using Entity;
using Entity.Sale;
using ServiceCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Dapper;
using ServiceCore.Tool.Mqtt;

namespace Customer.Bussiness_Service
{
    public interface Iqa_service
    {
        /// <summary>
        /// 绑定IC
        /// </summary>
        /// <param name="mchid"></param>
        /// <param name="sn"></param>
        /// <param name="box_code"></param>
        /// <returns></returns>
        ResultModel Ic_Bind(string mchid, string sn, string box_code);
        /// <summary>
        /// 绑定IC2
        /// </summary>
        /// <param name="mchid"></param>
        /// <param name="sn"></param>
        /// <param name="box_code"></param>
        /// <returns></returns>
        ResultModel Ic2_Bind(string sn, string box_code);
        /// <summary>
        /// IC解绑
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        ResultModel Ic_unBind(string Id);
        /// <summary>
        /// IC2解绑
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        ResultModel Ic2_unBind(string Id);
        /// <summary>
        /// 获取生产单详情
        /// </summary>
        /// <param name="work_order_details_id"></param>
        /// <returns></returns>
        ResultObjModel get_work_order_details_model(string work_order_details_id);
        /// <summary>
        /// 开始绑定生产单
        /// </summary>
        /// <param name="box_code"></param>
        /// <param name="work_order_details_id"></param>
        /// <returns></returns>
        ResultModel start_bind_workorder(string box_code, string work_order_details_id);
        /// <summary>
        ///  解绑生产单
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        ResultModel unbind_workorder(string id);
        /// <summary>
        /// 获取绑定列表
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        ResultListModel<Mch_bind_record_search> get_bind_pagelist(mch_Bind_params model);
        /// <summary>
        /// 生产主管查看管理
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        ResultListModel<Mch_bind_record_search> get_bind_pagelist_for_manage(mch_Bind_params_for_manage model);

        #region 电控开锁
        /// <summary>
        /// 发送开锁指令
        /// </summary>
        /// <param name="mchid"></param>
        /// <param name="boxno"></param>
        /// <returns></returns>
        ResultObjModel send_open_lock(string mchid, int? boxno);
        /// <summary>
        /// 查询锁状态
        /// </summary>
        /// <param name="lock_id"></param>
        /// <returns></returns>
        ResultObjModel search_lock_log(string lock_id);
        #endregion
    }
    public class qa_service : Iqa_service
    { 
        private readonly IToole_DI _tool;

        public readonly IRK_Mqtt _mqtt;
        public qa_service(IToole_DI Tool, IRK_Mqtt Mqtt)
        {
            _tool = Tool;
            _mqtt = Mqtt;
        }
        #region 关联管理系统机器绑定解绑逻辑  
        /// <summary>
        /// 绑定基础操作
        /// </summary>
        /// <param name="mchid"></param>
        /// <param name="sn"></param>
        /// <param name="box_code"></param>
        /// <param name="bindtype"></param>
        /// <returns></returns>
        private ResultModel base_bind(string mchid, string sn, string box_code, bind_type_enum bindtype)
        { 
            return CoreStartDo.ResultAction<ResultModel>(result =>
            {
                if (bindtype == bind_type_enum.IC)
                {
                    //如果当前IC调用 需要验证机器码
                    if (string.IsNullOrWhiteSpace(mchid))
                    {
                        result.code = 1;
                        result.msg = "机器ID不能为空";
                        return result;
                    }
                    if (_tool.di_user.USER.uid != "4" && mchid.Contains("WP2003075"))
                    {
                        result.code = 1;
                        result.msg = "非法的mchid号码段";
                        return result;
                    }
                }
                else
                {
                    //如果是其他的调用 则需要生成一个临时的机器码
                    mchid = GetNoByTimeStamp.Get();
                }
                if (string.IsNullOrWhiteSpace(sn))
                {
                    result.code = 1;
                    result.msg = "机器IMEI不能为空";
                    return result;
                }
                if (string.IsNullOrWhiteSpace(box_code))
                {
                    result.code = 1;
                    result.msg = "请扫描机器码";
                    return result;
                }
                
                //柜体码是否绑定到临时机器码上
                var checkinfo = _tool.di_db.Get_rk_List<Mch_bind_record>("select * from Mch_bind_record where (box_code=@box_code or mchid=@mchid or sn=@sn) and Type_id<=9", new { mchid, box_code, sn }).ToList();
                if (checkinfo.Any())
                {
                    //存在其他绑定记录遍历返回提醒
                    string errorrecord = "";
                    foreach (var item in checkinfo)
                    {
                        if (mchid == item.mchid)
                        {
                            errorrecord += $"机器ID {mchid}已存在绑定记录,";
                        }
                        else if (sn == item.sn)
                        {
                            errorrecord += $"IMEI {sn}已存在绑定记录,";
                        }
                        else if (box_code == item.box_code)
                        {
                            errorrecord += $"机器码 {box_code}已存在绑定记录,";
                        }
                    }
                    if (!string.IsNullOrWhiteSpace(errorrecord))
                    {
                        errorrecord = errorrecord.TrimEnd(',') + " 请先解绑后操作";
                    }
                    result.code = 1;
                    result.msg = errorrecord;
                    return result;
                }
                else {
                    //检测SN是否已经绑定到其他机器上了 用于旧的机器验证
                    Mch havemch = _tool.di_db.Get_rk_List<Mch>("select * from mch where sn=@sn", new { sn }).FirstOrDefault();
                    if (havemch != null)
                    { 
                        result.code = 1;
                        result.msg = "当前SN在系统内已绑定机器,可能为更换的旧驱动板,联系管理员处理";
                        return result;
                    }  
                }
                //柜体码是否绑定了生产单号
                var check_work_order = _tool.di_db.GetList<sale_work_order_details>("select top 1 * from sale_work_order_details where box_code=@box_code", new { box_code }).FirstOrDefault();
                if (check_work_order != null)
                {
                    result.code = 1;
                    result.msg = "当前机器已绑定了生产单号 请先解绑后操作";
                    return result;
                }
                //验证通过,开始构造数据
                Mch_bind_record record = new Mch_bind_record()
                {
                    addtime = DateTime.Now,
                    box_code = box_code,
                    Id = _tool.di_getid.IGet_SnowFlake_Id,
                    mchid = mchid,
                    sn = sn,
                    Type_id = bindtype,
                    uid = _tool.di_user.USER.uid,
                     u_name = _tool.di_user.USER.u_name
                };
                var startbind = _tool.di_db.do_rk_Execute(_tool.di_db.AddBySqlStr<Mch_bind_record>(), record);
                if (startbind > 0)
                {
                    result.code = 0;
                    result.msg = $"{bindtype.ToString()}绑定成功";
                    _tool.di_es.Add_Log($"==绑定成功==>{Newtonsoft.Json.JsonConvert.SerializeObject(record)}", "qabind"); 
                }
                else
                {
                    result.code = 1;
                    result.msg = $"{bindtype.ToString()}绑定失败";
                }
                return result;
            });
        }
        /// <summary>
        /// 解绑基础操作
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        private ResultModel base_unbind(string id)
        {
            return CoreStartDo.ResultAction(result =>
            {
                if (string.IsNullOrWhiteSpace(id))
                {
                    result.code = 1;
                    result.msg = "id不能为空";
                    return result;
                }
                //开始获取数据
                var check_mch_bind = _tool.di_db.Get_rk_List<Mch_bind_record>("select top 1 * from Mch_bind_record where Id=@id", new { id }).FirstOrDefault();
                if (check_mch_bind == null)
                {
                    result.code = 1;
                    result.msg = "绑定数据不存在";
                    return result;
                }

                //检测当前是否已经绑定了生产单
                if (!string.IsNullOrWhiteSpace(check_mch_bind.work_order_details_id))
                {
                    result.code = 1;
                    result.msg = "柜体码已绑定到生产单，请先前往生产单解绑后再进行操作";
                    return result;  
                }
                //直接删除对应数据
                int del_row = _tool.di_db.do_rk_Execute("delete from Mch_bind_record where Id=@id", new { id });
                if (del_row > 0)
                {
                    result.code = 0;
                    result.msg = "解绑成功";
                    _tool.di_es.Add_Log($"==解绑成功==>{Newtonsoft.Json.JsonConvert.SerializeObject(check_mch_bind)}", "qabind");
                }
                else
                {
                    result.code = 1;
                    result.msg = "解绑失败，没有数据被改变";
                }
                return result;
            });
        }
        /// <summary>
        /// 绑定IC
        /// </summary>
        /// <returns></returns>
        public ResultModel Ic_Bind(string mchid, string sn, string box_code)
        {
            return base_bind(mchid, sn, box_code, bind_type_enum.IC);
        }
        /// <summary>
        /// 绑定IC2
        /// </summary>
        /// <returns></returns>
        public ResultModel Ic2_Bind(string sn, string box_code)
        {
            return base_bind("", sn, box_code, bind_type_enum.IC2);
        }
        /// <summary>
        /// IC解绑
        /// </summary>
        /// <returns></returns>
        public ResultModel Ic_unBind(string Id)
        {
            return base_unbind(Id);
        }
        /// <summary>
        /// IC2解绑
        /// </summary>
        /// <param name="sn"></param>
        /// <param name="box_code"></param>
        /// <returns></returns>
        public ResultModel Ic2_unBind(string Id)
        {
            return base_unbind(Id);
        }
        /// <summary>
        ///  获取扫描出来的生产单基础数据
        /// </summary>
        /// <returns></returns> 
        public ResultObjModel get_work_order_details_model(string work_order_details_id)
        {
            return CoreStartDo.ResultAction(result =>
            {
                if (string.IsNullOrWhiteSpace(work_order_details_id))
                {
                    result.code = 1;
                    result.msg = "扫描数据不能为空";
                    return result;
                }
                //检测生产单是否存在
                var checkworkorder = _tool.di_db.GetList<checkworkorder_model>("select a.*,b.baseuserid,b.baseusername,b.mch_name,b.mch_id,b.work_end_time,b.total_state,c.u_name,b.mch_id from  sale_work_order_details  a left join sale_work_order b on a.work_order_id = b.work_order_id left join rk_user c on b.add_uid = c.uid where a.work_order_details_id=@work_order_details_id", new { work_order_details_id }).SingleOrDefault();
                result.code = 0;
                result.msg = "success";
                result.data = checkworkorder;
                return result;
            });
        }
        /// <summary>
        ///  绑定柜体和生产单
        /// </summary>
        /// <param name="box_code"></param>
        /// <param name="work_order_details_id"></param>
        /// <returns></returns>
        public ResultModel start_bind_workorder(string box_code, string work_order_details_id)
        {
            return CoreStartDo.ResultAction(result =>
            {
                if (string.IsNullOrWhiteSpace(box_code))
                {
                    result.code = 1;
                    result.msg = "柜体码不能为空";
                    return result;
                }
                if (string.IsNullOrWhiteSpace(work_order_details_id))
                {
                    result.code = 1;
                    result.msg = "生产单号不能为空";
                    return result;
                }
                //检测当前箱体好是否已经绑定过生产单了
                var check_bind_record = _tool.di_db.Get_rk_List<Mch_bind_record>("select * from Mch_bind_record where (box_code=@box_code or work_order_details_id=@work_order_details_id) and Type_id=10", new { box_code, work_order_details_id });
                if (check_bind_record.Any())
                {
                    //存在其他绑定记录遍历返回提醒
                    string errorrecord = "";
                    foreach (var item in check_bind_record)
                    {
                        if (box_code == item.box_code)
                        {
                            errorrecord += $"柜体码 {box_code}已存在绑定记录,";
                        }
                        else if (work_order_details_id == item.work_order_details_id)
                        {
                            errorrecord += $"生产单 {work_order_details_id}已存在绑定记录,";
                        }
                    }
                    if (!string.IsNullOrWhiteSpace(errorrecord))
                    {
                        errorrecord = errorrecord.TrimEnd(',') + " 请先解绑后操作";
                    }
                    result.code = 1;
                    result.msg = errorrecord;
                    return result;
                }
                //开始试图获取生产单号
                var checkworkorder = _tool.di_db.GetList<checkworkorder_model>("select a.*,b.baseuserid,b.baseusername,b.mch_name,b.mch_id,b.work_end_time,b.total_state,c.u_name,b.mch_id,b.create_order_time from  sale_work_order_details  a left join sale_work_order b on a.work_order_id = b.work_order_id left join rk_user c on b.add_uid = c.uid where a.work_order_details_id=@work_order_details_id", new { work_order_details_id }).SingleOrDefault();
                if (checkworkorder == null)
                {
                    result.code = 1;
                    result.msg = "生产单号不存在";
                    return result;
                }
                if (checkworkorder.total_state != sale_work_state_enum.生产已接单 && checkworkorder.total_state != sale_work_state_enum.生产中)
                {
                    result.code = 1;
                    result.msg = $"当前生产单状态{checkworkorder.total_state.ToString()} 不允许绑定";
                    return result;
                }
                string mchid = "";
                string sn = "";
                //如果当前生产单对应的柜体是主柜  则需要获取当前的柜体码已绑定的记录
                if (checkworkorder.box_No == 0)
                {
                    var master_box = _tool.di_db.Get_rk_List<Mch_bind_record>("select * from Mch_bind_record  where box_code=@box_code and Type_id<=9", new { box_code }).FirstOrDefault();
                    if (master_box == null)
                    {
                        result.code = 1;
                        result.msg = "当前生产单为主柜,必须先进行第一步绑定";
                        return result;
                    }
                    mchid = master_box.mchid;
                    sn = master_box.sn;
                    if (string.IsNullOrWhiteSpace(mchid) || string.IsNullOrWhiteSpace(mchid))
                    {
                        result.code = 1;
                        result.msg = "数据异常,第一步绑定未能成功绑定Imei和mchid";
                        return result;
                    }
                }
                #region 数据整合
                List<sql_tran_params> rk_sql = new List<sql_tran_params>();
                List<sql_tran_params> customer_sql = new List<sql_tran_params>();
                //无论如何 1.创建一条绑定记录
                //如果是副柜 2.将柜体码赋予到对应生产单详情下 3将柜体码赋予到rk柜体数据的下 
                //如果是主柜  4.更新当前机器对应主柜柜体码、id、sn并删除对应mchid的机器信息 5.根据生产单重置货道信息 6,更新机器ID到rk柜体数据下 7,更新生产单指定的机器mchid 

                #region 1.创建一条绑定记录 
                Mch_bind_record record = new Mch_bind_record()
                {
                    addtime = DateTime.Now,
                    box_code = box_code,
                    Id = _tool.di_getid.IGet_SnowFlake_Id,
                    mchid = mchid,
                    sn = sn,
                    Type_id = bind_type_enum.生产单,
                    work_order_id = checkworkorder.work_order_id,
                    work_order_details_id = checkworkorder.work_order_details_id,
                    uid = _tool.di_user.USER.uid,
                    u_name = _tool.di_user.USER.u_name
                };
                rk_sql.Add(new sql_tran_params() { sql = _tool.di_db.AddBySqlStr<Mch_bind_record>(), model = record });
                #endregion
                #region 2.将柜体码赋予到对应生产单详情下
                customer_sql.Add(new sql_tran_params() { sql = "update sale_work_order_details set box_code=@box_code where work_order_details_id=@work_order_details_id", model = new { work_order_details_id, box_code } });
                #endregion
                #region 3.将柜体码赋予到rk柜体数据下
                rk_sql.Add(new sql_tran_params() { sql = "update Mch_subsidiary set box_code=@box_code where work_order_id=@work_order_id and box_no=@box_no", model = new { box_code, checkworkorder.work_order_id, checkworkorder.box_No } });
                #endregion
                if (checkworkorder.box_No == 0)
                {
                    #region  4.更新当前机器对应主柜柜体码、id、sn并删除对应mchid的机器信息
                    rk_sql.Add(new sql_tran_params() { sql = "delete from Mch where Id=@old_mchid", model = new { old_mchid = mchid } });
                    rk_sql.Add(new sql_tran_params()
                    {
                        sql = "update Mch set Id=@mchid,box_code=@box_code,SN=@sn,work_order_id=@work_order_id,work_order_time=@work_order_time,work_baseuserid=@work_baseuserid where Id=@temp_mchid",
                        model = new
                        {
                            mchid,
                            sn,
                            box_code,
                            temp_mchid = checkworkorder.mch_id,
                            checkworkorder.work_order_id,
                            work_order_time = checkworkorder.create_order_time,
                            work_baseuserid = checkworkorder.baseuserid
                        }
                    });
                    #endregion
                    #region 5.根据生产单重置货道信息
                    //根据生产单格式化当前货道数据 根据生产单号获取货道生成信息
                    List<string> slotlist = _tool.di_db.GetList<string>("select slot_set from sale_work_order_details where work_order_id=@work_order_id", new { checkworkorder.work_order_id }).ToList();
                    List<slot_set> setlist = new List<slot_set>();
                    foreach (var item in slotlist)
                    {  
                        setlist.AddRange(Newtonsoft.Json.JsonConvert.DeserializeObject<List<slot_set>>(item.Replace("\\", "").TrimStart('"').TrimEnd('"')));
                    }
                    //删除之前可能存在的货道数据
                    rk_sql.Add(new sql_tran_params() { sql = "delete from Slot where Mchid=@old_mchid", model = new { old_mchid = mchid } });
                    //开始添加新的货道信息
                    List<Slot> SLotList = new List<Slot>();
                    foreach (var slotIndex in setlist)
                    {
                        int hei = 0;
                        try
                        {
                            hei = Convert.ToInt32(slotIndex.height);
                        }
                        catch { }
                        SLotList.Add(new Slot()
                        {
                            Id = $"{mchid}-{slotIndex.index}",
                            BaseUserId = checkworkorder.baseuserid,
                            cab = 0,
                            col = 0,
                            count = 0,
                            height = hei,
                            CreateOn = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
                            index = slotIndex.index,
                            IsDelete = false,
                            maxcount = slotIndex.maxcount,
                            MchId = mchid,
                            price = 0.01M,
                            SlotStateId = SlotState.可用,
                            SlotTypeId = SlotType.弹簧货道
                        });
                    }
                    rk_sql.Add(new sql_tran_params() { sql = _tool.di_db.AddBySqlStr<Slot>(), model = SLotList });
                    #endregion
                    #region 6,更新机器ID到rk柜体数据下
                    rk_sql.Add(new sql_tran_params() { sql = "update Mch_subsidiary set mchid=@mchid where work_order_id=@work_order_id", model = new { checkworkorder.work_order_id, mchid } });
                    #endregion
                    #region 7,更新生产单指定的机器mchid
                    customer_sql.Add(new sql_tran_params()
                    {
                        sql = "update sale_work_order set mch_id=@mchid,total_state=@total_state,work_state=@work_state,working_time=@working_time where work_order_id=@work_order_id",
                        model = new
                        {
                            checkworkorder.work_order_id,
                            mchid,
                            total_state = sale_work_state_enum.生产中,
                            work_state = work_state.生产中,
                            working_time = DateTime.Now
                        }
                    });
                    #endregion
                }
                string errormsg = "";
                int RKtranrow = _tool.di_db.StartRKTran((conn, tran) =>
                {
                    int rows = 0;
                    foreach (var item in rk_sql)
                    {
                        rows += conn.Execute(item.sql, item.model, tran);
                    }
                    return rows;
                }, ref errormsg);
                if (!string.IsNullOrWhiteSpace(errormsg))
                {
                    result.code = 1;
                    result.msg = "绑定失败 更新主库数据失败" + errormsg;
                }
                else
                {
                    int customer_tranrow = _tool.di_db.StartTran((conn, tran) =>
                    {
                        int rows = 0;
                        foreach (var item in  customer_sql)
                        {
                            rows += conn.Execute(item.sql, item.model, tran);
                        }
                        return rows;
                    }, ref errormsg);
                    if (!string.IsNullOrWhiteSpace(errormsg))
                    {
                        result.code = 1;
                        result.msg = "绑定失败 更新辅库数据失败" + errormsg;
                    }
                    else
                    {
                        result.code = 0;
                        result.msg = "绑定成功";
                    }
                }
                #endregion
                return result;
            });
        }
        /// <summary>
        ///  解绑生产单
        /// </summary>
        /// <param name="work_order_details_id"></param>
        /// <returns></returns>
        public ResultModel unbind_workorder(string id)
        {
            return CoreStartDo.ResultAction(result =>
            {
                if (string.IsNullOrWhiteSpace(id))
                {
                    result.code = 1;
                    result.msg = "绑定记录ID不能为空";
                    return result;
                }
                //获取绑定记录
                Mch_bind_record check_bind_record = _tool.di_db.Get_rk_List<Mch_bind_record>("select top 1 * from Mch_bind_record where Id=@id", new { id }).FirstOrDefault();
                if(check_bind_record== null)
                {
                    result.code = 1;
                    result.msg = "生产单绑定记录未找到";
                    return result;
                }
                if (!string.IsNullOrWhiteSpace(check_bind_record.mchid))
                {
                    var mchinfo = _tool.di_db.Get_rk_List<Mch>("select * from Mch where Id=@mchid", new { check_bind_record.mchid }).FirstOrDefault();
                    if (mchinfo != null)
                    {
                        if (mchinfo.BaseUserId.ToLower() != "rk_test")
                        {
                            result.code = 1;
                            result.msg = "当前机器已经被客户绑定，无法解绑生产单";
                            return result;
                        }
                    }
                }
                if (check_bind_record.Type_id != bind_type_enum.生产单)
                {
                    result.code = 1;
                    result.msg = "当前记录类型不正确";
                    return result;
                }
                //获取生产单信息 
                var checkworkorder = _tool.di_db.GetList<checkworkorder_model>("select a.*,b.baseuserid,b.baseusername,b.mch_name,b.mch_id,b.work_end_time,b.total_state,c.u_name,c.uid,b.mch_id from  sale_work_order_details  a left join sale_work_order b on a.work_order_id = b.work_order_id left join rk_user c on b.add_uid = c.uid where a.work_order_details_id=@work_order_details_id", new { check_bind_record.work_order_details_id }).SingleOrDefault();
                if (checkworkorder == null)
                {
                    result.code = 1;
                    result.msg = "生产单号不存在";
                    return result;
                } 
                if (checkworkorder.total_state == sale_work_state_enum.生产完成 || (checkworkorder.total_state < sale_work_state_enum.生产已接单 && checkworkorder.total_state > sale_work_state_enum.生产退回))
                {
                    result.code = 1;
                    result.msg = $"当前生产单状态{checkworkorder.total_state.ToString()} 不允许解绑生产单";
                    return result;
                }
                _tool.di_es.Add_Log($"准备解绑生产单=>{Newtonsoft.Json.JsonConvert.SerializeObject(new { check_bind_record.box_code, checkworkorder.box_No, checkworkorder.work_order_id, checkworkorder.work_order_details_id })}", "qabind");
                #region 数据整合
                List<sql_tran_params> rk_sql = new List<sql_tran_params>();
                List<sql_tran_params> customer_sql = new List<sql_tran_params>();
                //先顶一个临时的机器ID  肯定能用得到
                string Temp_mchid = "Temp_" + _tool.di_getid.IGet_SnowFlake_Id;
                //无论如何 1.删除对应记录数据
                //如果是副柜 2.将一个空值的柜体码赋予到对应生产单详情下 3将一个空值柜体码赋予到rk柜体数据的下 
                //如果是主柜 4.更新当前主柜对应机器id为一个temp数据,并且清空SN和绑定的box_code,并重新生成mchid的基础数据 5.删除货道信息 6,将重置的机器ID到rk柜体数据下 7,更新生产单指定的机器mchid   
                #region 1.创建一条绑定记录  
                rk_sql.Add(new sql_tran_params() { sql = "delete from Mch_bind_record where Id=@id", model = new { id } });
                #endregion
                #region 2.将一个空值的柜体码赋予到对应生产单详情下
                customer_sql.Add(new sql_tran_params() { sql = "update sale_work_order_details set box_code=null where work_order_details_id=@work_order_details_id", model = new { checkworkorder.work_order_details_id } });
                #endregion
                #region 3.将一个空值柜体码赋予到rk柜体数据的下
                rk_sql.Add(new sql_tran_params() { sql = "update Mch_subsidiary set box_code=null where work_order_id=@work_order_id and box_no=@box_no", model = new { checkworkorder.work_order_id, checkworkorder.box_No } });
                #endregion
                if (checkworkorder.box_No == 0)
                {
                    #region  4.更新当前主柜对应机器id为一个temp数据,并且清空SN和绑定的box_code,并重新生成mchid的基础数据 
                    rk_sql.Add(new sql_tran_params() { sql = "update Mch set Id=@temp_mchid,box_code=null,SN=null where Id=@mch_id", model = new { temp_mchid = Temp_mchid, checkworkorder.mch_id } });
                    //创建新机器
                    var mch = new Entity.Mch()
                    {
                        Id = checkworkorder.mch_id,
                        State = MchState.可用,
                        MchMode = checkworkorder.Mch_Type.ToString(),
                        IsDelete = false,
                        UpdateOn = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
                        CreateOn = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
                        work_baseuserid = checkworkorder.baseuserid,
                        sale_uid = checkworkorder.uid,
                        sale_name = checkworkorder.u_name
                    };
                    rk_sql.Add(new sql_tran_params() { sql = _tool.di_db.AddBySqlStr<Mch>(), model = mch });
                    #endregion
                    #region 5.根据生产单重置货道信息 
                    //删除之前可能存在的货道数据
                    rk_sql.Add(new sql_tran_params() { sql = "delete from Slot where Mchid=@old_mchid", model = new { old_mchid = checkworkorder.mch_id } });
                    #endregion
                    #region 6,更新机器ID到rk柜体数据下
                    rk_sql.Add(new sql_tran_params() { sql = "update Mch_subsidiary set mchid=@mchid where work_order_id=@work_order_id", model = new { checkworkorder.work_order_id, mchid = Temp_mchid } });
                    #endregion
                    #region 7,更新生产单指定的机器mchid
                    //customer_sql.Add(new sql_tran_params() { sql = "update sale_work_order set mchid=@mchid where work_order_id=@work_order_id", model = new { checkworkorder.work_order_id, mchid = Temp_mchid } });
                    customer_sql.Add(new sql_tran_params()
                    {
                        sql = "update sale_work_order set mch_id=@mchid,total_state=@total_state,work_state=@work_state,working_time=null where work_order_id=@work_order_id",
                        model = new
                        {
                            checkworkorder.work_order_id,
                            mchid = Temp_mchid,
                            total_state = sale_work_state_enum.生产已接单,
                            work_state = work_state.生产已接单
                        }
                    });
                    #endregion
                }
                string errormsg = "";
                int RKtranrow = _tool.di_db.StartRKTran((conn, tran) =>
                {
                    int rows = 0;
                    foreach (var item in rk_sql)
                    {
                        rows += conn.Execute(item.sql, item.model, tran);
                    }
                    return rows;
                }, ref errormsg);
                if (!string.IsNullOrWhiteSpace(errormsg))
                {
                    result.code = 1;
                    result.msg = "解绑失败 更新主库数据失败" + errormsg;
                }
                else
                {
                    int customer_tranrow = _tool.di_db.StartTran((conn, tran) =>
                    {
                        int rows = 0;
                        foreach (var item in customer_sql)
                        {
                            rows += conn.Execute(item.sql, item.model, tran);
                        }
                        return rows;
                    }, ref errormsg);
                    if (!string.IsNullOrWhiteSpace(errormsg))
                    {
                        result.code = 1;
                        result.msg = "解绑失败 更新辅库数据失败"+ errormsg;
                    }
                    else
                    {
                        result.code = 0;
                        result.msg = "解绑成功";
                    }
                }
                #endregion
                return result;

            });
        } 
        /// <summary>
        /// 获取绑定列表信息必须指定搜索类型
        /// </summary>
        /// <returns></returns>
        public ResultListModel<Mch_bind_record_search> get_bind_pagelist(mch_Bind_params model)
        {
            return CoreStartDo.ResultAction<ResultListModel<Mch_bind_record_search>>(result =>
            {
                if (!model.search_type.HasValue)
                {
                    result.code = 1;
                    result.msg = "必须上传搜索类型";
                    return result;
                }
                string sql = "select * from Mch_bind_record";
                string where = "where Type_id=@Type_id";
                string search_key = $"%{model.SerchKeyword}%";
                switch (model.search_type.Value)
                {
                    case bind_type_enum.IC:
                        //ID
                        where += " and mchid like @search_key";
                        break;
                    case bind_type_enum.IC2:
                        where += " and sn like @search_key";
                        //sn
                        break;
                    case bind_type_enum.生产单:
                        where += " and work_order_details_id like @search_key";
                        //单号
                        break;
                }
                if (!model.is_manage)
                {
                    where += " and uid=@uid";
                }
                result = _tool.di_db.GetRKPageList<Mch_bind_record_search>(sql, where, "addtime", new { Type_id = model.search_type, search_key, _tool.di_user.USER.uid }, model.IsPage, model.page, model.pagesize);
                return result;
            });      
        }  
        /// <summary>
        /// 获取绑定列表信息必须指定搜索类型
        /// </summary>
        /// <returns></returns>
        public ResultListModel<Mch_bind_record_search> get_bind_pagelist_for_manage(mch_Bind_params_for_manage model)
        {
            return CoreStartDo.ResultAction<ResultListModel<Mch_bind_record_search>>(result =>
            {
              
                string sql = "select * from Mch_bind_record";
                string where = "where 1=1";
                dynamic query_dy =  new System.Dynamic.ExpandoObject();
                if (!string.IsNullOrWhiteSpace(model.mchid))
                {
                    where += " and mchid like @mchid";
                    query_dy.mchid = $"%{model.mchid}%";
                }
                if (!string.IsNullOrWhiteSpace(model.sn))
                {
                    where += " and sn like @sn";
                    query_dy.sn = $"%{model.sn}%";
                }
                if (!string.IsNullOrWhiteSpace(model.box_code))
                {
                    where += " and box_code=@box_code";
                    query_dy.box_code = model.box_code;
                }
                if (!string.IsNullOrWhiteSpace(model.work_order_details_id))
                {
                    where += " and work_order_details_id=@work_order_details_id";
                    query_dy.work_order_details_id = model.work_order_details_id;
                }
                result = _tool.di_db.GetRKPageList<Mch_bind_record_search>(sql, where, "addtime", query_dy, model.IsPage, model.page, model.pagesize);
                return result;
            });
        }
        #endregion

        #region 电控开锁
        /// <summary>
        /// 设置开锁
        /// </summary>
        /// <returns></returns>
        public ResultObjModel send_open_lock(string mchid, int? boxno)
        {
            return CoreStartDo.ResultAction(result =>
            {
                if (string.IsNullOrWhiteSpace(mchid))
                {
                    result.code = 1;
                    result.msg = "机器ID未入参";
                    return result;
                }
                if (!boxno.HasValue)
                {
                    result.code = 1;
                    result.msg = "必须指定开锁柜";
                    return result;
                }
                Mch mch_mod = _tool.di_db.Get_rk_List<Mch>("select top 1 * from mch where Id=@id", new { id = mchid }).FirstOrDefault();
                if (mch_mod == null)
                {
                    result.code = 1;
                    result.msg = "机器不存在";
                    return result;
                }
                if (!mch_mod.IsOnLine)
                {
                    result.code = 1;
                    result.msg = "机器不在线";
                    return result;
                }
                if (mch_mod.BaseUserId.ToLower() != "rk_test")
                {
                    result.code = 1;
                    result.msg = "无法检测非测试环境账号";
                    return result;
                }
                //检测上一条是什么时候发的
                var locklog = _tool.di_db.Get_rk_List<RK_Lock_Log>("select top 1 * from RK_Lock_Log where mchid=@mchid order by sendtime desc", new { mchid = mch_mod.Id }).FirstOrDefault();
                if (locklog != null && locklog.sendtime >= DateTime.Now.AddSeconds(-30))
                {
                    result.code = 1;
                    result.msg = "发送过于频繁";
                    return result;
                }
                var log_user = _tool.di_user.USER;
                string lock_id = Guid.NewGuid().ToString("N");
                //构造开锁日志
                RK_Lock_Log newmod = new RK_Lock_Log()
                {
                    lock_id = lock_id,
                    boxno = boxno.Value,
                    ElecEn = 1,
                    ElecNum = 0,
                    ElecOnTi = 7,
                    ElecState = 1,
                    lock_log_state = lock_log_state.已发送,
                    mchid = mch_mod.Id,
                    sn = mch_mod.SN,
                    sendtime = DateTime.Now,
                    baseuserid = mch_mod.BaseUserId,
                    rk_userid = log_user.uid
                };
                string topic = $"rkt/mch/{mch_mod.SN}/lock/";
                string data = Newtonsoft.Json.JsonConvert.SerializeObject(new open_lock_params()
                {
                    msgid = lock_id,
                    ElecState = newmod.ElecState,
                    ElecEn = newmod.ElecEn,
                    boxno = newmod.boxno,
                    ElecNum = newmod.ElecNum,
                    ElecOnTi = newmod.ElecOnTi
                });
                _mqtt.Publish(topic, data, MQTTnet.Protocol.MqttQualityOfServiceLevel.ExactlyOnce); 
                _tool.di_db.do_rk_Execute(_tool.di_db.AddBySqlStr<RK_Lock_Log>(), newmod);
                result.code = 0;
                result.msg = "指令发送成功";
                result.data = newmod.lock_id;
                return result;
            });
        }

        /// <summary>
        /// 查询锁状态
        /// </summary>
        /// <returns></returns>
        public ResultObjModel search_lock_log(string lock_id)
        {
            return CoreStartDo.ResultAction(result =>
            {
                RK_Lock_Log log = _tool.di_db.Get_rk_List<RK_Lock_Log>("select top 1 * from RK_Lock_Log where lock_id=@lock_id", new { lock_id }).FirstOrDefault();
                if (log == null)
                {
                    result.code = 1;
                    result.msg = "日志不存在";
                    return result;
                }
                switch (log.lock_log_state)
                {
                    case lock_log_state.已发送:
                        //如果超过30秒还没有收到回复，那就直接超时
                        if (log.sendtime <= DateTime.Now.AddSeconds(-30))
                        {
                            _tool.di_db.do_rk_Execute("update RK_Lock_Log set lock_log_state=@lock_log_state,msg=@msg where lock_id=@lock_id", new
                            {
                                lock_id,
                                lock_log_state = lock_log_state.超时,
                                msg = "开锁失败:超时未响应"
                            });
                            result.code = 1;
                            result.msg = "开锁失败:超时未响应";
                            return result;
                        }
                        else
                        {
                            result.code = 2;
                            result.msg = "等待中...";
                            return result;
                        }
                    case lock_log_state.电控开锁:
                        result.code = 0;
                        result.data = log.msg;
                        return result;
                    default:
                        result.code = 1;
                        result.msg = $"开锁{log.lock_log_state.ToString()}:{log.msg}";
                        return result;
                }
            });
        }
        #endregion
    }
}
